<?php
declare (strict_types=1);

namespace app\middleware\common;

use app\model\AdminGroup;
use app\model\AdminGroupMenusRelation;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use think\Exception;

class Auth
{
    public function handle($request, \Closure $next)
    {
        try {
            $module = app('http')->getName();
            $action = request()->action();
            $authorization = $this->getAuthorization();

            if (!$authorization) throw new Exception('登录无效或已过期');
            $jwtInfo = (array)JWT::decode($authorization, new Key(env('jwt.admin_key'), 'HS256'));

            if (!$jwtInfo) throw new Exception('无效的登录信息');
            if ($jwtInfo['expire'] < time()) throw new Exception('登录过期，请重新登录');

            if (strtolower($module) !== $jwtInfo['module']) throw new Exception('超出授权范围');

            //+------------------------------
            //|菜单检测
            //+------------------------------
            $menuIdInHeader = request()->header('mid');
            $menuIds = app(AdminGroupMenusRelation::class)->where(['group_id' => $jwtInfo['groupId']])->column('menu_id');
            if (!in_array($menuIdInHeader, $menuIds) && !in_array($action, ['login', 'getUserInfo', 'getPermCode', 'getMenuList'])) {
                throw new Exception('未授权的访问菜单');
            }

            $request->currentModule = $jwtInfo['module'];
            $request->currentGid = $jwtInfo['groupId'] ?? null;
            $request->currentUid = $jwtInfo['userId'] ?? null;

            return $next($request);
        } catch (\Exception|\UnexpectedValueException $e) {
            return jsonReturn(false, lang($e->getMessage() . ':' . $e->getLine()), [], 401);
        }
    }

    private function getAuthorization(): string
    {
        $auth_param_name = config('common.auth_param_name') ?: 'authorization';
        $auth_param_name = strtolower($auth_param_name);
        $headers = request()->header();
        return $headers[$auth_param_name] ?? '';
    }
}
